home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / graphics / a-g / beyondthedark / developer / source / tron / tron.c < prev   
Encoding:
C/C++ Source or Header  |  1995-12-21  |  11.9 KB  |  425 lines

  1. /* Hop Library */
  2.  
  3. #include <exec/memory.h>
  4. #include <exec/execbase.h>
  5. #include <graphics/gfxbase.h>
  6. #include <intuition/intuitionbase.h>
  7. #include <libraries/iffparse.h>
  8. #include <utility/tagitem.h>
  9.  
  10. #include <clib/macros.h>
  11.  
  12. #define __USE_SYSBASE 42
  13.  
  14. #include <proto/exec.h>
  15. #include <proto/graphics.h>
  16. #include <proto/intuition.h>
  17. #include <proto/utility.h>
  18.  
  19. #include <math.h>
  20.  
  21. #include "BTD.h"
  22.  
  23. struct IntuitionBase *IntuitionBase;
  24. struct GfxBase *GfxBase;
  25. struct Library *UtilityBase;
  26.  
  27. struct Library *MathIeeeDoubBasBase,*MathIeeeDoubTransBase;
  28.  
  29. #define TRONTAG(o) (BTD_Client+(o))
  30.  
  31. #define TRON_Pixels     TRONTAG(0)
  32. #define TRON_NumPlayers TRONTAG(1)
  33.  
  34. #define MAX_PIXELS 20L /* Pixels per Frame */
  35. #define DEF_PIXELS 4L
  36.  
  37. #define DEF_NUM_PLAYERS 2
  38. #define MAX_NUM_PLAYERS 5
  39.  
  40. struct BTDInteger TronIntParams[] =
  41.  {
  42.   TRON_Pixels,"Pixels per Frame",BTDPT_INTEGER,DEF_PIXELS,1L,MAX_PIXELS,TRUE,
  43.   TRON_NumPlayers,"Number of Players",BTDPT_INTEGER,DEF_NUM_PLAYERS,2L,MAX_NUM_PLAYERS,TRUE
  44.  };
  45.  
  46. struct BTDNode *TronParams[] =
  47.  {
  48.   &TronIntParams[0].BI_Node,
  49.   &TronIntParams[1].BI_Node,
  50.   NULL
  51.  };
  52.  
  53. struct BTDInfo TronInfo =
  54.  {
  55.   BTDI_Revision,MAKE_ID('T','R','O','N'),
  56.   "Tron","Based on the movie Tron","Matthias Scheler",
  57.   TronParams
  58.  };
  59.  
  60. #define DIRECT_UP    0
  61. #define DIRECT_RIGHT 1
  62. #define DIRECT_DOWN  2
  63. #define DIRECT_LEFT  3
  64.  
  65. #define NUM_DIRECT 4
  66.  
  67. LONG XInc[NUM_DIRECT] = {0L,1L,0L,-1L};
  68. LONG YInc[NUM_DIRECT] = {-1L,0L,1L,0L};
  69.  
  70. ULONG Turn090[NUM_DIRECT] = {DIRECT_RIGHT,DIRECT_DOWN,DIRECT_LEFT,DIRECT_UP};
  71. ULONG Turn180[NUM_DIRECT] = {DIRECT_DOWN,DIRECT_LEFT,DIRECT_UP,DIRECT_RIGHT};
  72. ULONG Turn270[NUM_DIRECT] = {DIRECT_LEFT,DIRECT_UP,DIRECT_RIGHT,DIRECT_DOWN};
  73.  
  74. #define CRASH_DELAY 48L /* must be multiple of 6 */
  75.  
  76. struct TronStruct
  77.  {
  78.   struct BTDDrawInfo *ts_BTDDrawInfo;
  79.   LONG   ts_Left,ts_Top,ts_Right,ts_Bottom;
  80.   ULONG  ts_CrashDelay,ts_CrashIndex;
  81.   ULONG  ts_Pixels;
  82.   ULONG  ts_NumPlayers,ts_Alive;
  83.   LONG   ts_X[MAX_NUM_PLAYERS],ts_Y[MAX_NUM_PLAYERS];
  84.   ULONG  ts_Direct[MAX_NUM_PLAYERS],ts_Count[MAX_NUM_PLAYERS];
  85.   BYTE   *ts_CrashColor;
  86.   LONG   ts_RandN,ts_RandF,ts_RandI;
  87.  };
  88.  
  89. UBYTE TronRedTab[MAX_NUM_PLAYERS]   = {0xFF,0x00,0xFF,0x00,0xFF};
  90. UBYTE TronGreenTab[MAX_NUM_PLAYERS] = {0xFF,0x00,0x00,0xFF,0x00};
  91. UBYTE TronBlueTab[MAX_NUM_PLAYERS]  = {0x00,0xFF,0x00,0x00,0xFF};
  92.  
  93. /* library stuff */
  94.  
  95. char MyBlankerName[] = "tron.btd";
  96. char MyBlankerID[]   = "Tron Blanker V" VERSION "." REVISION " for BTD";
  97.  
  98. LONG MyBlankerLibInit(void)
  99.  
  100. {
  101.  if (GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L))
  102.   {
  103.    if (IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37L))
  104.     {
  105.      if (UtilityBase=OpenLibrary("utility.library",37L)) return TRUE;
  106.  
  107.      CloseLibrary (&IntuitionBase->LibNode);
  108.     }
  109.    CloseLibrary (&GfxBase->LibNode);
  110.   }
  111.  return FALSE;
  112. }
  113.  
  114. void MyBlankerLibFree(void)
  115.  
  116. {
  117.  CloseLibrary (UtilityBase);
  118.  CloseLibrary (&IntuitionBase->LibNode);
  119.  CloseLibrary (&GfxBase->LibNode);
  120. }
  121.  
  122. /* random generator */
  123.  
  124. void __regargs InitRandom(struct TronStruct *TronStruct,ULONG Instance)
  125.  
  126. {
  127.  ULONG Time[2];
  128.  
  129.  CurrentTime (&Time[0],&Time[1]);
  130.  TronStruct->ts_RandN=(LONG)Time[0];
  131.  
  132.  if (Time[1]<1024L) Time[1]|=1;
  133.  else Time[1]>>=10;
  134.  Time[1]^=Instance;
  135.  
  136.  TronStruct->ts_RandF=4*Time[1]+1;
  137.  TronStruct->ts_RandI=2*Time[1]+1;
  138. }
  139.  
  140. WORD __regargs Random(struct TronStruct *TronStruct,WORD Max)
  141.  
  142. {
  143.  TronStruct->ts_RandN=TronStruct->ts_RandF*TronStruct->ts_RandN+TronStruct->ts_RandI;
  144.  if (TronStruct->ts_RandN<0L) TronStruct->ts_RandN=-TronStruct->ts_RandN;
  145.  
  146.  return (WORD)(TronStruct->ts_RandN%Max);
  147. }
  148.  
  149. /* implementation of library functions */
  150.  
  151. struct BTDInfo *QueryMyBlanker(void)
  152.  
  153. {
  154.  return &TronInfo;
  155. }
  156.  
  157. LONG __regargs BorderDist(struct TronStruct *TronStruct,ULONG Index)
  158.  
  159. {
  160.  switch (TronStruct->ts_Direct[Index])
  161.   {
  162.    case DIRECT_UP:
  163.     return TronStruct->ts_Y[Index]-TronStruct->ts_Top;
  164.    case DIRECT_RIGHT:
  165.     return TronStruct->ts_Right-TronStruct->ts_X[Index];
  166.    case DIRECT_DOWN:
  167.     return TronStruct->ts_Bottom-TronStruct->ts_Y[Index];
  168.    case DIRECT_LEFT:
  169.     return TronStruct->ts_X[Index]-TronStruct->ts_Left;
  170.   }
  171.  return 0L;
  172. }
  173.  
  174. void __regargs PlaceCycle(struct TronStruct *TronStruct,ULONG Index)
  175.  
  176. {
  177.  struct BTDDrawInfo *BTDDrawInfo;
  178.  
  179.  BTDDrawInfo=TronStruct->ts_BTDDrawInfo;
  180.  do
  181.   {
  182.    TronStruct->ts_X[Index]=Random(TronStruct,BTDDrawInfo->BDI_Width-2L)+
  183.                            1L+TronStruct->ts_Left;
  184.    TronStruct->ts_Y[Index]=Random(TronStruct,BTDDrawInfo->BDI_Height-2L)+
  185.                            1L+TronStruct->ts_Top;
  186.   }
  187.  while (ReadPixel(BTDDrawInfo->BDI_RPort,
  188.                   TronStruct->ts_X[Index],TronStruct->ts_Y[Index])!=BTD_BgPen);
  189.  
  190.  TronStruct->ts_Direct[Index]=Random(TronStruct,NUM_DIRECT);
  191.  TronStruct->ts_Count[Index]=Random(TronStruct,BorderDist(TronStruct,Index))+1L;
  192.  
  193.  BTDDrawInfo->BDI_Red[BTDDrawInfo->BDI_Pens[Index]]=TronRedTab[Index];
  194.  BTDDrawInfo->BDI_Green[BTDDrawInfo->BDI_Pens[Index]]=TronGreenTab[Index];
  195.  BTDDrawInfo->BDI_Blue[BTDDrawInfo->BDI_Pens[Index]]=TronBlueTab[Index];
  196.  BTDDrawInfo->BDI_Changed[BTDDrawInfo->BDI_Pens[Index]]=TRUE;
  197.  
  198.  TronStruct->ts_CrashColor[BTDDrawInfo->BDI_Pens[Index]]=TRUE;
  199. }
  200.  
  201. struct TronStruct *InitMyBlanker(struct TagItem *TagList)
  202.  
  203. {
  204.  struct BTDDrawInfo *BTDDrawInfo;
  205.  struct TronStruct *TronStruct;
  206.  ULONG *Error,Dummy,Index;
  207.  UWORD MaxPen;
  208.  
  209.  if ((BTDDrawInfo=(struct BTDDrawInfo *)
  210.                    GetTagData(BTD_DrawInfo,NULL,TagList))==NULL) return NULL;
  211.  Error=(ULONG *)GetTagData(BTD_Error,(ULONG)&Dummy,TagList);
  212.  if ((TronStruct=AllocVec(sizeof(struct TronStruct),MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  213.   {
  214.    *Error=BTDERR_Memory;
  215.    return NULL;
  216.   }
  217.  InitRandom (TronStruct,GetTagData(BTD_Instance,0L,TagList));
  218.  
  219.  TronStruct->ts_BTDDrawInfo=BTDDrawInfo;
  220.  TronStruct->ts_Left=BTDDrawInfo->BDI_Left;
  221.  TronStruct->ts_Top=BTDDrawInfo->BDI_Top;
  222.  TronStruct->ts_Right=BTDDrawInfo->BDI_Left+BTDDrawInfo->BDI_Width-1;
  223.  TronStruct->ts_Bottom=BTDDrawInfo->BDI_Top+BTDDrawInfo->BDI_Height-1;
  224.  TronStruct->ts_Pixels=GetTagData(TRON_Pixels,DEF_PIXELS,TagList);
  225.  TronStruct->ts_NumPlayers=GetTagData(TRON_NumPlayers,DEF_NUM_PLAYERS,TagList);
  226.  
  227.  MaxPen=BTDDrawInfo->BDI_Pens[0];
  228.  for (Index=1L; Index<TronStruct->ts_NumPlayers; Index++)
  229.   if (MaxPen<BTDDrawInfo->BDI_Pens[Index]) MaxPen=BTDDrawInfo->BDI_Pens[Index];
  230.  
  231.  if ((TronStruct->ts_CrashColor=AllocVec(MaxPen+1L,MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  232.   {
  233.    FreeVec (TronStruct);
  234.    *Error=BTDERR_Memory;
  235.    return NULL;
  236.   }
  237.  
  238.  for (Index=0L; Index<TronStruct->ts_NumPlayers; Index++)
  239.   PlaceCycle (TronStruct,Index);
  240.  TronStruct->ts_Alive=Index;
  241.  
  242.  return TronStruct;
  243. }
  244.  
  245. void EndMyBlanker(struct TronStruct *TronStruct)
  246.  
  247. {
  248.  FreeVec (TronStruct->ts_CrashColor);
  249.  FreeVec (TronStruct);
  250. }
  251.  
  252. LONG __regargs BorderDistDirect(struct TronStruct *TronStruct,ULONG Index,ULONG Direct)
  253.  
  254. {
  255.  switch (Direct)
  256.   {
  257.    case DIRECT_UP:
  258.     return TronStruct->ts_Y[Index]-TronStruct->ts_Top;
  259.    case DIRECT_RIGHT:
  260.     return TronStruct->ts_Right-TronStruct->ts_X[Index];
  261.    case DIRECT_DOWN:
  262.     return TronStruct->ts_Bottom-TronStruct->ts_Y[Index];
  263.    case DIRECT_LEFT:
  264.     return TronStruct->ts_X[Index]-TronStruct->ts_Left;
  265.   }
  266.  return 0L;
  267. }
  268.  
  269. int __regargs CheckCrash(struct TronStruct *TronStruct,ULONG Index,ULONG Direct)
  270.  
  271. {
  272.  return TronStruct->ts_CrashColor[ReadPixel(TronStruct->ts_BTDDrawInfo->BDI_RPort,
  273.                                             TronStruct->ts_X[Index]+XInc[Direct],
  274.                                             TronStruct->ts_Y[Index]+YInc[Direct])];
  275. }
  276.  
  277. void __regargs TurnCycle(struct TronStruct *TronStruct,ULONG Index)
  278.  
  279. {
  280.  ULONG NewDirect[2],Dist[2];
  281.  ULONG Num;
  282.  
  283.  if (BorderDist(TronStruct,Index)==0L)
  284.   {
  285.    if (BorderDistDirect(TronStruct,Index,Turn090[TronStruct->ts_Direct[Index]])==0L)
  286.     {
  287.      TronStruct->ts_Direct[Index]=Turn270[TronStruct->ts_Direct[Index]];
  288.      return;
  289.     }
  290.    if (BorderDistDirect(TronStruct,Index,Turn270[TronStruct->ts_Direct[Index]])==0L)
  291.     {
  292.      TronStruct->ts_Direct[Index]=Turn090[TronStruct->ts_Direct[Index]];
  293.      return;
  294.     }
  295.  
  296.    if (CheckCrash(TronStruct,Index,Turn090[TronStruct->ts_Direct[Index]]))
  297.     {
  298.      TronStruct->ts_Direct[Index]=Turn270[TronStruct->ts_Direct[Index]];
  299.      return;
  300.     }
  301.    if (CheckCrash(TronStruct,Index,Turn270[TronStruct->ts_Direct[Index]]))
  302.     {
  303.      TronStruct->ts_Direct[Index]=Turn090[TronStruct->ts_Direct[Index]];
  304.      return;
  305.     }
  306.  
  307.    Num=2L;
  308.    NewDirect[0]=Turn090[TronStruct->ts_Direct[Index]];
  309.    NewDirect[1]=Turn270[TronStruct->ts_Direct[Index]];
  310.   }
  311.  else
  312.   {
  313.    Num=0L;
  314.  
  315.    if (Dist[Num]=BorderDistDirect(TronStruct,Index,Turn090[TronStruct->ts_Direct[Index]]))
  316.     if (!CheckCrash(TronStruct,Index,Turn090[TronStruct->ts_Direct[Index]]))
  317.      NewDirect[Num++]=Turn090[TronStruct->ts_Direct[Index]];
  318.  
  319.    if (Dist[Num]=BorderDistDirect(TronStruct,Index,Turn270[TronStruct->ts_Direct[Index]]))
  320.     if (!CheckCrash(TronStruct,Index,Turn270[TronStruct->ts_Direct[Index]]))
  321.      NewDirect[Num++]=Turn270[TronStruct->ts_Direct[Index]];
  322.   }
  323.  
  324.  if (Num<2L)
  325.   {
  326.    if (Num) TronStruct->ts_Direct[Index]=NewDirect[0];
  327.    return;
  328.   }
  329.  
  330.  TronStruct->ts_Direct[Index]=NewDirect[(Random(TronStruct,Dist[0]+Dist[1])<Dist[0])?0:1];
  331. }
  332.  
  333. void AnimMyBlanker(struct TronStruct *TronStruct)
  334.  
  335. {
  336.  if (TronStruct->ts_CrashDelay)
  337.   {
  338.    struct BTDDrawInfo *BTDDrawInfo;
  339.    ULONG Index;
  340.  
  341.    BTDDrawInfo=TronStruct->ts_BTDDrawInfo;
  342.    Index=TronStruct->ts_CrashIndex;
  343.    switch (TronStruct->ts_CrashDelay%6)
  344.     {
  345.      case 0:
  346.       BTDDrawInfo->BDI_Red[BTDDrawInfo->BDI_Pens[Index]]=255;
  347.       BTDDrawInfo->BDI_Green[BTDDrawInfo->BDI_Pens[Index]]=255;
  348.       BTDDrawInfo->BDI_Blue[BTDDrawInfo->BDI_Pens[Index]]=255;
  349.       BTDDrawInfo->BDI_Changed[BTDDrawInfo->BDI_Pens[Index]]=TRUE;
  350.       break;
  351.      case 3:
  352.       BTDDrawInfo->BDI_Red[BTDDrawInfo->BDI_Pens[Index]]=TronRedTab[Index];
  353.       BTDDrawInfo->BDI_Green[BTDDrawInfo->BDI_Pens[Index]]=TronGreenTab[Index];
  354.       BTDDrawInfo->BDI_Blue[BTDDrawInfo->BDI_Pens[Index]]=TronBlueTab[Index];
  355.       BTDDrawInfo->BDI_Changed[BTDDrawInfo->BDI_Pens[Index]]=TRUE;
  356.     }
  357.  
  358.    if (--TronStruct->ts_CrashDelay==0L)
  359.     if (--TronStruct->ts_Alive==1L)
  360.      {
  361.       EraseRect (TronStruct->ts_BTDDrawInfo->BDI_RPort,
  362.                  TronStruct->ts_Left,TronStruct->ts_Top,
  363.                  TronStruct->ts_Right,TronStruct->ts_Bottom);
  364.  
  365.       for (Index=0L; Index<TronStruct->ts_NumPlayers; Index++)
  366.        PlaceCycle (TronStruct,Index);
  367.       TronStruct->ts_Alive=Index;
  368.      }
  369.     else
  370.      {
  371.       BTDDrawInfo->BDI_Red[BTDDrawInfo->BDI_Pens[Index]]=0;
  372.       BTDDrawInfo->BDI_Green[BTDDrawInfo->BDI_Pens[Index]]=0;
  373.       BTDDrawInfo->BDI_Blue[BTDDrawInfo->BDI_Pens[Index]]=0;
  374.       BTDDrawInfo->BDI_Changed[BTDDrawInfo->BDI_Pens[Index]]=TRUE;
  375.  
  376.       TronStruct->ts_CrashColor[BTDDrawInfo->BDI_Pens[Index]]=FALSE;
  377.      }
  378.   }
  379.  else
  380.   {
  381.    ULONG Pixels,Index;
  382.  
  383.    Pixels=TronStruct->ts_Pixels;
  384.    while (Pixels--)
  385.     for (Index=0L; Index<TronStruct->ts_NumPlayers; Index++)
  386.      if (TronStruct->ts_CrashColor[TronStruct->ts_BTDDrawInfo->BDI_Pens[Index]])
  387.       {
  388.        if (--TronStruct->ts_Count[Index]==0L)
  389.         {
  390.          TurnCycle (TronStruct,Index);
  391.          TronStruct->ts_Count[Index]=Random(TronStruct,BorderDist(TronStruct,Index))+1L;
  392.         }
  393.  
  394.        if (TronStruct->ts_CrashColor[ReadPixel(TronStruct->ts_BTDDrawInfo->BDI_RPort,
  395.                                                TronStruct->ts_X[Index],TronStruct->ts_Y[Index])])
  396.         {
  397.          TronStruct->ts_CrashDelay=CRASH_DELAY;
  398.          TronStruct->ts_CrashIndex=Index;
  399.          return;
  400.         }
  401.        else
  402.         {
  403.          SetAPen (TronStruct->ts_BTDDrawInfo->BDI_RPort,TronStruct->ts_BTDDrawInfo->BDI_Pens[Index]);
  404.          WritePixel (TronStruct->ts_BTDDrawInfo->BDI_RPort,
  405.                      TronStruct->ts_X[Index],TronStruct->ts_Y[Index]);
  406.         }
  407.  
  408.        TronStruct->ts_X[Index]+=XInc[TronStruct->ts_Direct[Index]];
  409.        TronStruct->ts_Y[Index]+=YInc[TronStruct->ts_Direct[Index]];
  410.  
  411.        if (TronStruct->ts_Count[Index]>1L)
  412.         if (CheckCrash(TronStruct,Index,TronStruct->ts_Direct[Index]))
  413.          TronStruct->ts_Count[Index]=1L;
  414.       }
  415.   }
  416.  
  417.  WaitTOF();
  418. }
  419.  
  420. ULONG PenCountMyBlanker(struct TagItem *TagList)
  421.  
  422. {
  423.  return GetTagData(TRON_NumPlayers,DEF_NUM_PLAYERS,TagList);
  424. }
  425.